package com.ttx;


import java.io.*;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;


/**
 * Created by ttx on 20/09/2017.
 */
public class Main {

    public static Properties readProp(String path){
        Properties prop = new Properties();
        try {
            FileInputStream fis = new FileInputStream(path);
            prop.load(fis);
            System.out.println("dataFilePath: " + prop.getProperty("dataFilePath"));
            System.out.println("rootFilePath: " + prop.getProperty("rootSavePath"));

        } catch (Exception e) {
            e.printStackTrace();
        }
        return prop;
    }

    public static  List<List<List<String>>> readArticles(Properties prop,List<List<String>> articleStringsList){
        List<List<List<String>>> urlForThreads = new ArrayList<>();
        ExecutorService executorService = Executors.newCachedThreadPool();
        for(List<String> articleStrings:articleStringsList){
            List<List<String>> urls = new ArrayList<>();
            executorService.execute(new URLExtractor(prop, urls, articleStrings));
            urlForThreads.add(urls);
        }
        executorService.shutdown();
        try{
            executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
        System.out.println("??");
        return urlForThreads;
    }

    public static void main(String[] args) {
        long time1 = System.currentTimeMillis();
        System.out.println("Initialize");
        Properties prop = readProp("settings.properties");
        List<List<String>> articleStringsList = divideArticle(prop);
        if(articleStringsList == null){
            System.exit(1);
        }
        System.out.println("Start reading articles");
        List<List<List<String>>> urlForThreads = readArticles(prop, articleStringsList);
        System.out.println(countURLNum(urlForThreads));
        countDifferentArticle(articleStringsList);

        ExecutorService exec = Executors.newCachedThreadPool();
        for (List<List<String>> urls:urlForThreads) {
            exec.execute(new ImageDownloader(prop.getProperty("rootSavePath"), urls) );
        }
        exec.shutdown();

        try{
            exec.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("undownloaded imamge:" + ImageDownloader.failNum);
        System.out.println("used time:" + (System.currentTimeMillis() - time1));


    }

    private static int countURLNum(List<List<List<String>>> urlForThreads){
        int num = 0;
        int count = 0;
        Set<String> set = new HashSet<>();
        for(List<List<String>> urlForThread:urlForThreads){
            for(List<String> urlForArticle:urlForThread){
                for(String url:urlForArticle){
                    set.add(url);
                    count++;
                }
            }
        }
        System.out.println(count);

        return set.size();

    }

    private static int countDifferentArticle(List<List<String>> articleStringsList){
        int count = 0;
        Set<String> set = new HashSet<>();
        for(List<String> articles:articleStringsList){
            for(String article:articles){
                count++;
                set.add(article);
            }
        }
        System.out.println("article count:" + count);
        System.out.println("different article count:" + set.size());
        return set.size();
    }

    private static List<List<String>> divideArticle(Properties prop) {
        int threadNum = Integer.parseInt(prop.getProperty("threadNum"));
        String dataFilePath = prop.getProperty("dataFilePath");
        List<List<String>> articleStrings = new ArrayList<>();

        try {
            BufferedReader bufferedReader = new BufferedReader(new FileReader(new File(dataFilePath)));
            try {
                for (int i = 0; i < threadNum; i++) {
                    articleStrings.add(new ArrayList<String>());
                }
                int count = 0;
                String singleArticleString;
                while((singleArticleString = bufferedReader.readLine()) != null){
                    articleStrings.get(count++ % threadNum).add(singleArticleString);
                }
            } catch (IOException e) {
                e.printStackTrace();
                return null;
            }
        } catch (FileNotFoundException e) {
            System.out.println("数据文件不存在");
            return null;
        }
        return articleStrings;
    }
}
